package com.suray.wcs.service.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.suray.wcs.res.enums.PalletStatus;
import com.suray.wcs.res.enums.RgvStatus;
import com.suray.wcs.service.core.util.DateUtil;
import com.suray.wcs.service.enums.ElectricStatus;
import com.suray.wcs.service.pojo.BaseEum;
import com.suray.wcs.service.system.entity.InterfaceLogDB;
import com.suray.wcs.service.system.entity.RgvHeartLogDB;
import com.suray.wcs.service.system.mapper.RgvHeartLogMapper;
import com.suray.wcs.service.system.service.IRgvHeartLogService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class RgvHeartLogServiceImpl extends ServiceImpl<RgvHeartLogMapper, RgvHeartLogDB> implements IRgvHeartLogService {
    @Autowired
    private RgvHeartLogMapper rgvHeartLogMapper;
    static final Long INTERVAL_TIME = Long.valueOf(60);

    @Override
    public List<RgvHeartLogDB> getRgvHeartLogsList(RgvHeartLogDB rgvHeartLogdb) {
        QueryWrapper<RgvHeartLogDB> queryWrapper = new QueryWrapper();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (rgvHeartLogdb.getDeviceName() != null) {
            queryWrapper.lambda().like(RgvHeartLogDB::getDeviceName, rgvHeartLogdb.getDeviceName());
        }
        if (rgvHeartLogdb.getRgvStatus() != null) {
            queryWrapper.lambda().eq(RgvHeartLogDB::getRgvStatus, rgvHeartLogdb.getRgvStatus());
        }
        if (rgvHeartLogdb.getPalletStatus() != 0) {
            queryWrapper.lambda().eq(RgvHeartLogDB::getPalletStatus, rgvHeartLogdb.getPalletStatus());
        }
        if (rgvHeartLogdb.getSendTimeStart() != null) {
            queryWrapper.lambda().ge(RgvHeartLogDB::getSendTime, formatter.format(rgvHeartLogdb.getSendTimeStart()));
        }
        if (rgvHeartLogdb.getSendTimeEnd() != null) {
            queryWrapper.lambda().lt(RgvHeartLogDB::getSendTime, formatter.format(rgvHeartLogdb.getSendTimeEnd()));
        }
        if (rgvHeartLogdb.getElectricStart() != null) {
            queryWrapper.lambda().ge(RgvHeartLogDB::getElectric, rgvHeartLogdb.getElectricStart());
        }
        if (rgvHeartLogdb.getElectricEnd() != null) {
            queryWrapper.lambda().lt(RgvHeartLogDB::getElectric, rgvHeartLogdb.getElectricEnd());
        }
        queryWrapper.orderByDesc("send_time");

        return rgvHeartLogMapper.getRgvHeartLogs(rgvHeartLogdb);
    }

    @Override
    public List<RgvHeartLogDB> getRgvHeartLogs(RgvHeartLogDB rgvHeartLogdb) {
        QueryWrapper<RgvHeartLogDB> queryWrapper = new QueryWrapper();
        if (rgvHeartLogdb.getDeviceName() != null) {
            queryWrapper.lambda().like(RgvHeartLogDB::getDeviceName, rgvHeartLogdb.getDeviceName());
        }
        if (rgvHeartLogdb.getRgvStatus() != null) {
            queryWrapper.lambda().eq(RgvHeartLogDB::getRgvStatus, rgvHeartLogdb.getRgvStatus());
        }
        if (rgvHeartLogdb.getPalletStatus() != null) {
            queryWrapper.lambda().eq(RgvHeartLogDB::getPalletStatus, rgvHeartLogdb.getPalletStatus());
        }
        if (rgvHeartLogdb.getElectricStart() != null) {
            queryWrapper.lambda().ge(RgvHeartLogDB::getElectric, rgvHeartLogdb.getElectricStart());
        }
        if (rgvHeartLogdb.getElectricEnd() != null) {
            queryWrapper.lambda().lt(RgvHeartLogDB::getElectric, rgvHeartLogdb.getElectricEnd());
        }
        queryWrapper.lambda().eq(RgvHeartLogDB::getTaskResult, rgvHeartLogdb.getTaskResult());
        if (!org.springframework.util.StringUtils.isEmpty(rgvHeartLogdb.getParams().get("beginTime"))) {
            queryWrapper.lambda().ge(RgvHeartLogDB::getSendTime, rgvHeartLogdb.getParams().get("beginTime"));
        }
        if (!org.springframework.util.StringUtils.isEmpty(rgvHeartLogdb.getParams().get("endTime"))) {
            queryWrapper.lambda().le(RgvHeartLogDB::getSendTime, rgvHeartLogdb.getParams().get("endTime"));
        }
        queryWrapper.orderByDesc("send_time");

        return rgvHeartLogMapper.selectList(queryWrapper);
    }

    @Override
    public boolean setInterfaceLog(RgvHeartLogDB rgvHeartLogdb) {
        return this.save(rgvHeartLogdb);
    }

    @Override
    public void deleteRgvHeartLog() {
        rgvHeartLogMapper.delRgvHeartLog(new Date());
    }

    @Override
    public void deleteThreeDaysAgoLog(Integer days) {
        rgvHeartLogMapper.deleteThreeDaysAgoLog(days, new Date());
    }

    @Override
    public List<Map<String, Object>> getGraphData(RgvHeartLogDB rgvHeartLogdb) {
        List<Map<String, Object>> dataList = Lists.newArrayList();
        if (StringUtils.isBlank(rgvHeartLogdb.getDeviceName())) {
            return dataList;
        }
        List<RgvHeartLogDB> rgvHeartLogDBList = rgvHeartLogMapper.getGraphData(rgvHeartLogdb);
        Map<String, RgvHeartLogDB> sendTimeStrMap = Maps.newHashMap();
        Date sendTimeStart = rgvHeartLogdb.getSendTimeStart();
        if (CollectionUtils.isNotEmpty(rgvHeartLogDBList)) {
            //比较第一条心跳数据的时间是否和开始时间一致
            //找出所有分钟内有心跳的记录，取第一条
            for (RgvHeartLogDB rgvHeartLog : rgvHeartLogDBList) {
                Date sendTime = rgvHeartLog.getSendTime();
                String sendTimeStr = DateUtil.format(sendTime, DateUtil.HM);
                if (sendTimeStrMap.containsKey(sendTimeStr)) {
                    continue;
                } else {
                    sendTimeStrMap.put(sendTimeStr, rgvHeartLog);
                }
            }
        }
        fillDataList(sendTimeStart, dataList, sendTimeStrMap);
        return dataList;
    }

    @Override
    public List<BaseEum> queryRgvStutas() {
        List<RgvStatus> rgvStatus = (Arrays.asList(RgvStatus.values()));
        List<BaseEum> rgvStatusList = new ArrayList<BaseEum>();
        for (RgvStatus status : rgvStatus) {
            rgvStatusList.add(new BaseEum(status.getRgvStatus(), status.toString()));
        }
        return rgvStatusList;
    }

    @Override
    public List<BaseEum> querypalletStatus() {
        List<PalletStatus> palletStatuses = (Arrays.asList(PalletStatus.values()));
        List<BaseEum> palletStatusList = new ArrayList<BaseEum>();
        for (PalletStatus status : palletStatuses) {
            palletStatusList.add(new BaseEum(status.getStatusNum(), status.toString()));
        }
        return palletStatusList;
    }

    @Override
    public int deleteLogByIds(Long[] interfaceLogIds) {
        return rgvHeartLogMapper.deleteLogByIds(interfaceLogIds);
    }

    @Override
    public void cleanLog() {
        rgvHeartLogMapper.cleanLog();
    }


    private void fillDataList(Date sendTimeStart, List<Map<String, Object>> dataList, Map<String, RgvHeartLogDB> sendTimeStrMap) {
        for (int i = 0; i <= 12; i++) {
            String sendTimeStr = DateUtil.format(sendTimeStart, DateUtil.HM);
            if (sendTimeStrMap.size() > 0 && sendTimeStrMap.containsKey(sendTimeStr)) {
                addMap(sendTimeStrMap.get(sendTimeStr), dataList, sendTimeStr);
            } else {
                addMap(null, dataList, sendTimeStr);
            }
            sendTimeStart = DateUtil.addSeconds(sendTimeStart, 5 * INTERVAL_TIME.intValue());
        }
    }

    private void addMap(RgvHeartLogDB rgvHeaLogdb, List<Map<String, Object>> dataList, String xValue) {
        if (rgvHeaLogdb != null) {
            if (rgvHeaLogdb.getElectric() != 0) {
                dataList.add(fillDataMap(rgvHeaLogdb.getElectric(), rgvHeaLogdb.getRgvStatus(), xValue));
            } else {
                dataList.add(fillDataMap(RgvStatus.UNKNOWN.getRgvStatus(), ElectricStatus.ERROR_BATTERY.getElectricStatus(), xValue));
            }
        } else {
            dataList.add(fillDataMap(0, 0, xValue));
        }
    }

    private Map<String, Object> fillDataMap(Integer battery, int carStatus, String xValue) {
        Map<String, Object> dataMap = Maps.newHashMap();
        dataMap.put("battery", battery);
        dataMap.put("carStatus", carStatus);
        dataMap.put("xValue", xValue);
        return dataMap;
    }

    /**
     * 字符串数组转为byte数组
     *
     * @param strs
     * @return
     */
    public static byte[] strToByteList(String[] strs) {
        byte[] result = new byte[strs.length];
        for (int i = 0; i < strs.length; i++) {
            result[i] = Byte.parseByte(strs[i]);
        }
        return result;
    }

}
